package com.jinke.api.modules.third.shipber.util;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.jinke.api.common.annotation.Apilog;
import com.jinke.api.common.exception.Asserts;
import com.jinke.api.common.util.CommonUtil;
import com.jinke.api.modules.third.ezeeship.model.request.EstimateRateRequest;
import com.jinke.api.modules.third.ezeeship.util.EzeeShipUtil;
import com.jinke.api.modules.third.shipber.model.request.CancelRequest;
import com.jinke.api.modules.third.shipber.model.request.CreateOrderRequest;
import com.jinke.api.modules.ums.model.Channel;
import com.jinke.api.modules.ums.vo.UserChannelVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
@RequiredArgsConstructor
public class ShipberlUtil {
    //取消
    public static final String LABEL_CANCEL = "https://api.shipber.com/v1/open-api/label/cancel";
    //预估
    public static final String API_RATE = "https://api.shipber.com/v1/open-api/rate";
    //下单
    public static final String LABEL = "https://api.shipber.com/open-api/v2/label";
    private static String apiKey = "39098ku0815svm7xdu3y";
    private static String apiSecret = "mDKC_0XIWYqqStpmSAjf6n2XFhA4ykEAFczlw6189DbS8cp3l4lANWkTStjcLjWo";


    public String sendPostRequest(String url, String requestBody) throws IOException {
        String seq = CommonUtil.getOrderNo();
        log.info("send :  {}, {}", seq, requestBody);
        HttpURLConnection connection = null;
        try {
            // 创建连接
            // 创建连接
            URL apiUrl = new URL(url);
            if ("true".equals(System.getenv("local"))) {
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 7890));
                connection = (HttpURLConnection) apiUrl.openConnection(proxy);
            } else {
                connection = (HttpURLConnection) apiUrl.openConnection();
            }

            connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Api-Key", apiKey);
            connection.setRequestProperty("Api-Secret", apiSecret);
            connection.setDoOutput(true);

            // 写入请求体
            try (OutputStream outputStream = connection.getOutputStream()) {
                outputStream.write(requestBody.getBytes("UTF-8"));
            }
            int responseCode = connection.getResponseCode();

            if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST) {
                // 获取错误消息体
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) {
                    StringBuilder errorResponse = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        errorResponse.append(line);
                    }
                    log.error("Error response :  {}, {}", seq, errorResponse.toString());
                    return errorResponse.toString();
                }
            } else {
                // 获取正常响应
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    log.info("rec :  {}, {}", seq, response.toString());
                    return response.toString();
                }
            }

        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    @Apilog(requestTypeName = "ShipBer-估价")
    public String getPrice(EstimateRateRequest estimateRateRequest) {
        String orderNO = estimateRateRequest.getOrderNO();
        try {
            // 发送POST请求
            CreateOrderRequest createOrderRequest = getCreateOrderRequest(estimateRateRequest);
            String param = JSON.toJSONString(createOrderRequest);
            log.info("Shipber 估价请求参数--------------->,{},{}", orderNO, param);
            String request = sendPostRequest(API_RATE, param);
            log.info("Shipber 估价请求响应结果--------------->,{},{}", orderNO, request);
            return request;
        } catch (IOException e) {
            log.info("Shipber 估价异常--------------->,{}", orderNO);
            e.printStackTrace();
        }
        return Strings.EMPTY;
    }

    @Apilog(requestTypeName = "ShipBer-下单")
    public String createOrder(EstimateRateRequest estimateRateRequest) {
        try {
            CreateOrderRequest createOrderRequest = getCreateOrderRequest(estimateRateRequest);
            log.info("ShipBer 下单参数---------------->，{}，{}", estimateRateRequest.getOrderNO(), JSON.toJSONString(createOrderRequest));
            String request = sendPostRequest(LABEL, JSON.toJSONString(createOrderRequest));
            log.info("ShipBer 下单响应结果---------------->，{}，{}", estimateRateRequest.getOrderNO(), request);
            return request;
        } catch (IOException e) {
            log.info("ShipBer 下单接口异常---------------->，{}", estimateRateRequest.getOrderNO());
            e.printStackTrace();
        }
        return Strings.EMPTY;
    }

    /**
     * 取消
     *
     * @param objectId
     * @param orderNo
     * @return
     */
    @Apilog(requestTypeName = "ShipBer-取消")
    public String cancelLabel(String objectId, String orderNo) {
        CancelRequest request = new CancelRequest();
        request.setOrderNum(objectId);
        String requestBody = JSON.toJSONString(request);
        try {
            // 发送POST请求
            String param = JSON.toJSONString(requestBody);
            log.info("--------------ShipBer取消参数---------------->，{}，{}", orderNo, param);
            String result = sendPostRequest(LABEL_CANCEL, param);
            log.info("--------------ShipBer取消响应---------------->，{}，{}", orderNo, result);
            return result;

        } catch (IOException e) {
            e.printStackTrace();
        }
        return Strings.EMPTY;
    }


    @NotNull
    private CreateOrderRequest getCreateOrderRequest(EstimateRateRequest estimateRateRequest) {
        // 将OrderRequest对象转换为JSON字符串
        // 创建OrderRequest对象
        CreateOrderRequest orderRequest = new CreateOrderRequest();

        CreateOrderRequest.Shipment shipment = new CreateOrderRequest.Shipment();
        // 设置属性值
        shipment.setCarrier(estimateRateRequest.getCarrierCode());
        shipment.setServiceCode(estimateRateRequest.getServiceCode());

        // 创建Orders对象

        orderRequest.setCustomOrderNum(estimateRateRequest.getPlatformNo());
        CreateOrderRequest.ShipFrom shipFrom = new CreateOrderRequest.ShipFrom();
        shipFrom.setUuid(estimateRateRequest.getUserChannelVO().getChannel().getUuid());
        shipment.setShipFrom(shipFrom);

        EstimateRateRequest.Address to = estimateRateRequest.getTo();
        CreateOrderRequest.ShipTo shipTo = new CreateOrderRequest.ShipTo();
        shipTo.setName(to.getPersonName());
        List<String> addressLines = new ArrayList<>();
        addressLines.add(to.getAddressLine1());
        if (StringUtils.isNotEmpty(to.getAddressLine2())) {
            addressLines.add(to.getAddressLine2());
        }
        shipTo.setAddresses(addressLines);
        shipTo.setCity(to.getCity());
        shipTo.setStateProvinceCode(to.getStateCode());
        shipTo.setPostalCode(to.getZipCode());
        shipTo.setPhone(to.getPhone());
        shipTo.setCountryCode(to.getCountryCode());
        shipTo.setIsResidential(to.getIsResidential());
        shipment.setShipTo(shipTo);

        String shipDate = estimateRateRequest.getShipDate();
        if (StringUtils.isBlank(shipDate)) {
            Asserts.fail("取件日期不能为空");
        }

        String inputDateString = "yyyy-MM-dd HH:mm:ss";
        String outputDateString = "yyyyMMdd";
        SimpleDateFormat inputDateFormat = new SimpleDateFormat(inputDateString);
        SimpleDateFormat outputDateFormat = new SimpleDateFormat(outputDateString);
        Date date = null;
        try {
            date = inputDateFormat.parse(shipDate);
            if (date.before(new Date())) {
                Asserts.fail("日期必须大于当前时间");
            }
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        String outputDateStr = outputDateFormat.format(date);
        shipment.setPickupDate(outputDateStr);

        List<EstimateRateRequest.Parcel> requestParcels = estimateRateRequest.getParcels();

        shipment.setPackageType(new CreateOrderRequest.PackageType("common", "Package"));
        shipment.setLabelSpecification(new CreateOrderRequest.LabelSpecification("pdf"));

        List<CreateOrderRequest.Package> packageList = requestParcels.stream().map(x -> {

            CreateOrderRequest.Package pkg = new CreateOrderRequest.Package();
            // 创建Parcels对象
            CreateOrderRequest.Dimension dimension = new CreateOrderRequest.Dimension();
            BigDecimal length = BigDecimal.valueOf(Double.parseDouble(x.getLength()));
            BigDecimal width = BigDecimal.valueOf(Double.parseDouble((x.getWidth())));
            BigDecimal height = BigDecimal.valueOf(Double.parseDouble(x.getHeight()));
            dimension.setLength(length);
            dimension.setWidth(width);
            dimension.setHeight(height);
            dimension.setCode(x.getDistanceUnit());
            pkg.setDimension(dimension);

            CreateOrderRequest.Weight weightObj = new CreateOrderRequest.Weight();
            BigDecimal weight = BigDecimal.valueOf(Double.parseDouble(x.getWeight()));
            weightObj.setValue(weight);
            weightObj.setCode(x.getMassUnit());
            pkg.setWeight(weightObj);


            EstimateRateRequest.LabelExtra extra = estimateRateRequest.getExtra();
            if (extra != null) {
                List<CreateOrderRequest.ReferenceNumber> referenceNumbers = new ArrayList<>();
                String reference = extra.getReference();
                if (StringUtils.isNotBlank(reference)) {
                    CreateOrderRequest.ReferenceNumber referenceNumber = new CreateOrderRequest.ReferenceNumber();
                    referenceNumber.setCode("reference #1");
                    referenceNumber.setValue(reference);
                    referenceNumbers.add(referenceNumber);
                }
                String reference2 = extra.getReference2();
                if (StringUtils.isNotBlank(reference2)) {
                    CreateOrderRequest.ReferenceNumber referenceNumber = new CreateOrderRequest.ReferenceNumber();
                    referenceNumber.setCode("reference #2");
                    referenceNumber.setValue(reference2);
                    referenceNumbers.add(referenceNumber);
                }
                pkg.setReferenceNumbers(referenceNumbers);
            }

            pkg.setConfirmation("None");
            pkg.setQuantity(x.getPackageNum());

            return pkg;
        }).collect(Collectors.toList());
        shipment.setPackages(packageList);

        orderRequest.setShipment(shipment);

        return orderRequest;
    }


}
